<?php

Raise::load('core.RaiseStaticClass');
Raise::load('core.Rectangle');
Raise::load('core.RaiseVariable');
Raise::load('core.RaiseDateTime');
Raise::load('core.RaiseCollection');
Raise::load('core.RaisePoint');

/**
 * Convert helper class
 * for conversion related functionality
 * 
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core
 * @since 1.2
 */
class RaiseConvert extends RaiseStaticClass {

    /**
     * Convert to string
     * @param mixed $a Value to be converted
     * @return string String value of $a
     */
    public static function toString($a){
        return strval($a);
    }

    /**
     * Convert to integer
     * @param mixed $a Value to be converted
     * @return int Integer value of $a
     */
    public static function toInteger($a){
        return intval($a);
    }

    /**
     * Convert to boolean
     * @param mixed $a Value to be converted
     * @return bool Bool value of $a
     */
    public static function toBoolean($a){
        return (bool)$a;
    }

    /**
     * Convert to array
     * @param mixed $a Value to be converted
     * @return array Array value of $a
     */
    public static function toArray($a){
        if($a instanceof Rectangle){
            return $a->toArray();
        }
        return (array)$a;
    }

    /**
     * Convert to object
     * @param mixed $a Value to be converted
     * @return object Object value of $a
     */
    public static function toObject($a){
        return (object)$a;
    }

    /**
     * Convert to double
     * @param mixed $a Value to be converted
     * @return double Double value of $a
     */
    public static function toDouble($a){
        return doubleval($a);
    }

    /**
     * Convert to RaiseDateTime
     * @param string|integer $a String value to be converted
     * @return RaiseDateTime DateTime value of $a
     */
    public static function toDateTime($a){
        if(RaiseVariable::getDataType($a) == RaiseVariable::TYPESTRING){
            return RaiseDateTime::fromString($a);
        }elseif(RaiseVariable::getDataType($a) == RaiseVariable::TYPEINTEGER){
            return RaiseDateTime::fromTimestamp($a);
        }elseif(RaiseVariable::isA($a, 'RaiseDateTime')){
            return $a;
        }
        return RaiseDateTime::Now();
    }

    /**
     * Convert array or RaiseCollection to JSON string
     * @param array|RaiseCollection $a value to be converted
     * @return string JSON string of array $a
     */
    public static function toJSONString($a){
        if($a instanceof RaiseCollection){
            $a = $a->toArray();
        }
        return json_encode($a);
    }

    /**
     * Convert JSON string to RaiseCollection
     * @param string $a JSON string to be converted
     * @return RaiseCollection Array value of string $a
     */
    public static function fromJSONString($a){
        return new RaiseCollection(json_decode(self::toString($a), true));
    }

    /**
     * Convert a rectangle, array or string into a RaisePoint
     * @param Rectangle|string|array $s The Rectangle or string to convert
     * @return RaisePoint
     */
    public static function toPoint($s){
        if(RaiseVariable::isType($s, 'Rectangle')){
            return $s->location();
        }elseif(RaiseVariable::isType($s, array('RaiseCollection', RaiseVariable::TYPEARRAY))){
            return new RaisePoint($s[0], $s[1]);
        }elseif(RaiseVariable::isType($s, RaiseVariable::TYPESTRING)){
            // parse strings like "20, 40"
            $comma = strpos($s, ',');
            $x = RaiseConvert::toDouble(trim(substr($s, 0, $comma)));
            $y = Raiseconvert::toDouble(trim(substr($s, $comma + 1)));
            return new RaisePoint($x, $y);
        }elseif(RaiseVariable::isType($s, 'RaisePoint')){
            return $s;
        }
        return RaisePoint::zero();
    }

    /**
     * Convert a string or array into a Rectangle
     * @param array|string $s The Rectangle or string to convert
     * @return Rectangle
     */
    public static function toRectangle($s){
        if(RaiseVariable::isType($s, array('RaiseCollection', RaiseVariable::TYPEARRAY))){
            return new Rectangle(new RaisePoint(RaiseConvert::toDouble($s[0]), RaiseConvert::toDouble($s[1])), RaiseConvert::toDouble($s[2]), RaiseConvert::toDouble($s[3]));
        }elseif(RaiseVariable::isType($s, RaiseVariable::TYPESTRING)){
            // parse strings like "20, 40"
            $v = explode(',', $s);
            if(count($v) == 4){
                return new Rectangle(RaiseConvert::toDouble(trim($v[0])), RaiseConvert::toDouble(trim($v[1])), RaiseConvert::toDouble(trim($v[2])), RaiseConvert::toDouble(trim($v[3])));
            }
        }
        return new Rectangle(RaisePoint::zero(), 0, 0);
    }

    /**
     * Convert from binary to decimal
     * @param string $a The binary string to convert
     * @return integer The decimal
     * @static
     * @link http://php.net/bindec
     */
    public static function binaryToDecimal($a){
        return bindec($a);
    }

    /**
     * Convert from decimal to binary string
     * @param integer $a The decimal number to convert
     * @return string The binary string
     * @static
     * @link http://php.net/decbin
     */
    public static function decimalToBinary($a){
        return decbin($a);
    }

    /**
     * Convert from binary string to hexadecimal string
     * @param string $a The binary string to convert
     * @return string The hexadecimal string
     * @static
     * @link http://php.net/bin2hex
     */
    public static function binaryToHexadecimal($a){
        return dechex(bindec($a));
    }

    /**
     * Convert from hexadecimal string to binary string
     * @param string $a The hexadecimal string to convert
     * @return string The binary string
     */
    public static function hexadecimalToBinary($a){
        return self::decimalToBinary(self::hexadecimalToDecimal($a));
    }

    /**
     * Convert from hexadecimal string to decimal
     * @param string $a The hexadecimal string to convert
     * @return integer The decimal number
     * @static
     * @link http://php.net/hexdec
     */
    public static function hexadecimalToDecimal($a){
        return hexdec($a);
    }

    /**
     * Convert from decimal to hexadecimal string
     * @param integer $a The decimal number to convert
     * @return string The hexadecimal string
     * @static
     * @link http://php.net/dechex
     */
    public static function decimalToHexadecimal($a){
        return dechex($a);
    }

    /**
     * Convert a decimal number to octal number
     * @param integer $a The decimal number
     * @return integer The octal number
     * @static
     * @link http://php.net/decoct
     */
    public static function decimalToOctal($a){
        return decoct($a);
    }

    /**
     * Convert a octal number to decimal number
     * @param integer $a The octal number
     * @return integer The decimal number
     * @static
     * @link http://php.net/octdec
     */
    public static function octalToDecimal($a){
        return octdec($a);
    }

    /**
     * Converts a number in degree to radian
     * @param number $d The number in degree to convert
     * @return number The number $d in radian
     * @static
     * @link http://php.net/deg2rad
     */
    public static function degreeToRadian($d){
        return deg2rad($d);
    }

    /**
     * Converts a number in radian to degree
     * @param number $d The number in radian to convert
     * @return number The number $d in degree
     * @static
     * @link http://php.net/rad2deg
     */
    public static function radianToDegree($r){
        return rad2deg($r);
    }

    /**
     * Converts from a Base64 Encoded String to the normal string
     * @param string $s
     * @return string
     * @static
     * @link http://php.net/base64-decode
     */
    public static function fromBase64($s){
        return base64_decode($s);
    }

    /**
     * Converts a string to base64 encoded
     * @param string $s
     * @return string
     * @static
     * @link http://php.net/base64-encode
     */
    public static function toBase64($s){
        return base64_encode($s);
    }

    /**
     * Convert a number between arbitrary bases
     * @param string $a The number to convert
     * @param integer $from The base number to convert from
     * @param integer $to The base number to conert to
     * @return string
     * @static
     * @link http://www.php.net/base-convert
     */
    public static function arbitraryBase($a, $from, $to){
        return base_convert($a, $from, $to);
    }
}
